package org.webcamp.users.services.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.webcamp.email.services.EmailService;
import org.webcamp.users.dao.UsersDao;
import org.webcamp.users.dto.User;
import org.webcamp.users.services.PasswordService;
import org.webcamp.users.services.UsersService;

public class UsersServiceImpl implements UsersService {

	private Logger log = Logger.getLogger(getClass());
	private UsersDao usersDao;
	private EmailService emailService;
	private PasswordService passwordService;
	private String url;
	
	public void setUrl(String url) {
		this.url = url;
	}

	public void setPasswordService(PasswordService passwordService) {
		this.passwordService = passwordService;
	}

	public void setEmailService(EmailService emailService) {
		this.emailService = emailService;
	}

	public void setUsersDao(UsersDao usersDao) {
		this.usersDao = usersDao;
	}

	@Override
	public void saveUser(User user) {
		log.info("Saving user " + user);
		usersDao.saveUser(user);
	}

	@Override
	public User loadUserByEmail(String email) {
		log.info("Loading user by email " + email);
		return usersDao.loadUserByEmail(email);
	}

	@Override
	public void resetPassword(String email) {
		// новый пароль
		String newPassword = passwordService.generatePassword();

		// достать существующего пользователя
		User user = usersDao.loadUserByEmail(email);
		if (user != null){
			// устанавливаем пользователю новый хэш от нового пароля
			user.setPasswordHash(passwordService.calculatePasswordHash(newPassword));
			// сохраняем пользователя
			usersDao.saveUser(user);
			
			Map<String, String> messageModel = new HashMap<>();
			messageModel.put("name", user.getName());
			messageModel.put("password", newPassword);
			messageModel.put("email", email);
			messageModel.put("url", url);

			emailService.sendEmail(email, "resetPassword", messageModel);
			log.info("Password was reset for user " + user);
		}
	}

	@Override
	public void registerUser(String email, String name) {
		User user = usersDao.loadUserByEmail(email);
		if (user != null){
			//TODO сделать нормальные исключения
			throw new RuntimeException("User already exists");
		}
		
		// генерим пользователю новый пароль
		String password = passwordService.generatePassword();
		
		// создаем объект для нового пользователя и заполняем его свойства
		user = new User();
		user.setEmail(email);
		user.setName(name);
		// устанавливаем хэш от нового пароля
		user.setPasswordHash(passwordService.calculatePasswordHash(password));
		// сохраняем
		usersDao.saveUser(user);

		Map<String, String> messageModel = new HashMap<>();
		messageModel.put("name", name);
		messageModel.put("email", email);
		messageModel.put("password", password);
		messageModel.put("url", url);

		// отсылаем пользователю имейл о регистрации
		emailService.sendEmail(email, "registration", messageModel);
	}

	@Override
	public User login(String email, String password) {
		// достаем пользователя
		User user = usersDao.loadUserByEmail(email);
		if (user == null || !user.getPasswordHash().equals(passwordService.calculatePasswordHash(password))){
			//TODO сделать нормальные исключения
			throw new RuntimeException("Incorrect login or password");
		}
		return user;
	}

	public void initUsers() {
		List<User> allUsers = usersDao.loadAllUsers();
		boolean adminFound = false;
		for (User user : allUsers) {
			if ("admin".equals(user.getName())) {
				adminFound = true;
				break;
			}
		}
		if (!adminFound) {
			User admin = new User();
			admin.setEmail("vladk1976@gmail.com");
			admin.setName("admin");
			admin.setPasswordHash(passwordService.calculatePasswordHash("xquesty"));
			usersDao.saveUser(admin);
			System.out.println("Admin user was created with default settings");
		}
		log.info("Users Service initialized");
	}
}
